import React, { useRef, useEffect, useState } from 'react';

interface CanvasProps {
  width: number;
  height: number;
}

const Canvas: React.FC<CanvasProps> = ({ width, height }) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [color, setColor] = useState('#000000');
  const [isErasing, setIsErasing] = useState(false);
  const [lineWidth, setLineWidth] = useState(2);
  const [history, setHistory] = useState<string[]>([]);
  const [historyIndex, setHistoryIndex] = useState(-1);
  const [scale, setScale] = useState(1);
  const [showGrid, setShowGrid] = useState(false);
  const [backgroundColor, setBackgroundColor] = useState('#ffffff');
  
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    
    const context = canvas.getContext('2d');
    if (!context) return;
    
    // 初始化画布
    context.fillStyle = backgroundColor;
    context.fillRect(0, 0, width, height);
    context.strokeStyle = isErasing ? backgroundColor : color;
    context.lineWidth = isErasing ? 20 : lineWidth;
    context.lineCap = 'round';
    
    // 绘制网格
    if (showGrid) {
      context.strokeStyle = '#cccccc';
      context.lineWidth = 0.5;
      const gridSize = 20;
      
      // 绘制垂直线
      for (let x = 0; x <= width; x += gridSize) {
        context.beginPath();
        context.moveTo(x, 0);
        context.lineTo(x, height);
        context.stroke();
      }
      
      // 绘制水平线
      for (let y = 0; y <= height; y += gridSize) {
        context.beginPath();
        context.moveTo(0, y);
        context.lineTo(width, y);
        context.stroke();
      }
      
      // 恢复绘制设置
      context.strokeStyle = isErasing ? backgroundColor : color;
      context.lineWidth = isErasing ? 20 : lineWidth;
    }
    
    // 绘制功能
    let isDrawing = false;
    let lastX = 0;
    let lastY = 0;
    
    const getCoordinates = (e: MouseEvent | TouchEvent): [number, number] => {
      if (e instanceof MouseEvent) {
        return [e.offsetX, e.offsetY];
      } else {
        const touch = e.touches[0];
        const rect = canvas.getBoundingClientRect();
        return [
          (touch.clientX - rect.left) / scale,
          (touch.clientY - rect.top) / scale
        ];
      }
    };
    
    const startDrawing = (e: MouseEvent | TouchEvent) => {
      isDrawing = true;
      [lastX, lastY] = getCoordinates(e);
    };
    
    const draw = (e: MouseEvent | TouchEvent) => {
      if (!isDrawing) return;
      const [currentX, currentY] = getCoordinates(e);
      context.beginPath();
      context.moveTo(lastX, lastY);
      context.lineTo(currentX, currentY);
      context.stroke();
      [lastX, lastY] = [currentX, currentY];
    };
    
    const stopDrawing = () => {
      isDrawing = false;
      saveCanvasState();
    };
    
    // 鼠标事件
    canvas.addEventListener('mousedown', startDrawing);
    canvas.addEventListener('mousemove', draw);
    canvas.addEventListener('mouseup', stopDrawing);
    canvas.addEventListener('mouseout', stopDrawing);
    
    // 触摸事件
    canvas.addEventListener('touchstart', startDrawing);
    canvas.addEventListener('touchmove', draw);
    canvas.addEventListener('touchend', stopDrawing);
    canvas.addEventListener('touchcancel', stopDrawing);
    
    return () => {
      // 清理鼠标事件
      canvas.removeEventListener('mousedown', startDrawing);
      canvas.removeEventListener('mousemove', draw);
      canvas.removeEventListener('mouseup', stopDrawing);
      canvas.removeEventListener('mouseout', stopDrawing);
      
      // 清理触摸事件
      canvas.removeEventListener('touchstart', startDrawing);
      canvas.removeEventListener('touchmove', draw);
      canvas.removeEventListener('touchend', stopDrawing);
      canvas.removeEventListener('touchcancel', stopDrawing);
    };
  }, [width, height, scale, showGrid, backgroundColor]);

  const clearCanvas = () => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    
    const context = canvas.getContext('2d');
    if (!context) return;
    
    context.fillStyle = backgroundColor;
    context.fillRect(0, 0, width, height);
    saveCanvasState();
  };
  
  const saveCanvasState = () => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    
    const dataUrl = canvas.toDataURL();
    setHistory(prev => {
      const newHistory = prev.slice(0, historyIndex + 1);
      newHistory.push(dataUrl);
      return newHistory;
    });
    setHistoryIndex(prev => prev + 1);
  };
  
  const undo = () => {
    if (historyIndex <= 0) return;
    
    const newIndex = historyIndex - 1;
    setHistoryIndex(newIndex);
    restoreCanvasState(history[newIndex]);
  };
  
  const redo = () => {
    if (historyIndex >= history.length - 1) return;
    
    const newIndex = historyIndex + 1;
    setHistoryIndex(newIndex);
    restoreCanvasState(history[newIndex]);
  };
  
  const restoreCanvasState = (dataUrl: string) => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    
    const context = canvas.getContext('2d');
    if (!context) return;
    
    const img = new Image();
    img.onload = () => {
      context.clearRect(0, 0, width, height);
      context.drawImage(img, 0, 0);
    };
    img.src = dataUrl;
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
      <div style={{ display: 'flex', gap: '10px' }}>
        <input 
          type="color" 
          value={color} 
          onChange={(e) => {
            setColor(e.target.value);
            setIsErasing(false);
          }} 
        />
        <input 
          type="color" 
          value={backgroundColor} 
          onChange={(e) => setBackgroundColor(e.target.value)} 
          title="背景色"
        />
        <button onClick={() => setIsErasing(!isErasing)}>
          {isErasing ? '画笔' : '橡皮擦'}
        </button>
        <button onClick={clearCanvas}>清除画布</button>
        <button onClick={undo} disabled={historyIndex <= 0}>撤销</button>
        <button onClick={redo} disabled={historyIndex >= history.length - 1}>重做</button>
        <input 
          type="range" 
          min="1" 
          max="20" 
          value={lineWidth} 
          onChange={(e) => setLineWidth(parseInt(e.target.value))}
        />
        <input 
          type="range" 
          min="0.5" 
          max="2" 
          step="0.1"
          value={scale} 
          onChange={(e) => setScale(parseFloat(e.target.value))}
        />
        <button onClick={() => setShowGrid(!showGrid)}>
          {showGrid ? '隐藏网格' : '显示网格'}
        </button>
        <button onClick={() => {
          const canvas = canvasRef.current;
          if (!canvas) return;
          const dataUrl = canvas.toDataURL('image/png');
          const link = document.createElement('a');
          link.download = 'drawing.png';
          link.href = dataUrl;
          link.click();
        }}>保存画布</button>
      </div>
      <div style={{ 
        overflow: 'hidden',
        border: '1px solid black',
        backgroundColor: backgroundColor
      }}>
        <canvas
          ref={canvasRef}
          width={width}
          height={height}
          style={{ 
            transform: `scale(${scale})`,
            transformOrigin: 'top left'
          }}
        />
      </div>
    </div>
  );
};

export default Canvas;